package com.atguigu.tingshu.album.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import com.atguigu.tingshu.album.config.MinioClientConfig;
import com.atguigu.tingshu.album.config.MinioConstantProperties;
import com.atguigu.tingshu.album.service.FileUploadService;
import com.atguigu.tingshu.common.execption.GuiguException;
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.errors.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

@Service
@Slf4j
public class FileUploadServiceImpl implements FileUploadService {

    @Autowired
    private MinioClient minioClient;

    @Autowired
    private MinioConstantProperties properties;


    /**
     * 文件上传接口
     * @param file
     * @return
     */
    @Override
    public String fileUpload(MultipartFile file) {
        String fileName = null;
        try {
            //0.因为用户行为不可控 所以先判断用户上传的是否为图片 用工具类ImageIO
            BufferedImage read = ImageIO.read(file.getInputStream());
            if(read==null){
                throw new GuiguException(400,"用户上传图片格式非法，请重新输入");
            }

            //1.创建Minio客户端实例 如果放在这里 对象实例存在堆内存中 每次上传图片都会创建一个对象实例存在堆内存中 会造成堆内存溢出
            //所以通过配置类创建 因为spring容器中的bean对象是单实例 然后通过自动装配 注入使用

            //2.判断桶是否存在
            // Check whether 'my-bucketname' exists or not.
            boolean found =
                    minioClient.bucketExists(BucketExistsArgs.builder().bucket(properties.getBucketName()).build());
            if (!found) {
                //3.创建桶
                // Create bucket with default region.
                minioClient.makeBucket(
                        MakeBucketArgs.builder()
                                .bucket(properties.getBucketName())
                                .build());
            }else {
                System.out.println("bucket"+properties.getBucketName()+"already exists ");
            }

            //4.设置文件路径 整个文件包含文件夹名称 上传文件名 后缀名
            //4.1文件夹名称 一般用日期来表示 获取当前日期 用到工具类DateUtil
            String folderName ="/"+ DateUtil.today()+"/";
            //4.2 文件名 一般用随机数来表示 保证文件名不重复 用到工具类IdUtil
            fileName = IdUtil.randomUUID();
            //4.3 获取后缀名 用到FileUtil工具类
            String extName = FileUtil.extName(file.getOriginalFilename());
            fileName = folderName+fileName+"."+extName;

            //5.文件上传
            minioClient.putObject(
                    PutObjectArgs.builder().bucket(properties.getBucketName()).object(fileName).stream(
                                    file.getInputStream(), file.getSize(), -1)
                            .contentType(file.getContentType())
                            .build());
        } catch (Exception e) {
            log.error("文件上传失败!message:{}",e);
            throw new RuntimeException(e);
        }

        //6.构建文件路径url并返回
        String url = properties.getEndpointUrl()+"/"+properties.getBucketName()+fileName;



        return url;





    }


}
